home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / DJSRC111.ZIP / go32 / dpmi.asm < prev    next >
Assembly Source File  |  1993-08-29  |  24KB  |  1,016 lines

  1. ; original Copyright(C) 1992 Hiroya Tsubakimoto
  2. ; modifications Copyright(C) 1993 Charles Sandmann
  3. ; Merged with GO32 V1.09+ C. Sandmann sandmann@clio.rice.edu
  4. ; Distributed under terms of "copying.dj" when distributed with GO32 source
  5. ; Distributed under terms of GPL if used in any other code
  6.  
  7.     .386p
  8.     include    segdefs.inc
  9.     include    tss.inc
  10.  
  11. ;*--------------------------------------------------------------*
  12. ;DGROUP group _TEXT,_DATA,_BSS  ;(tiny model only)
  13.  
  14. DPMIinfo    struc
  15. vers        db    ?,?
  16. flags        dw    ?
  17. cpu        dw    ?
  18. PIC        db    ?,?
  19. DPMIinfo    ends
  20.  
  21. DPMImemory    struc
  22. address        dd    ?
  23. bytes        dd    ?
  24. handle        dd    ?
  25. DPMImemory    ends
  26.  
  27. regs    struc
  28. rDI    dw    ?,?
  29. rSI    dw    ?,?
  30. rBP    dw    ?,?
  31.     dd    0
  32. rBX    dw    ?,?
  33. rDX    dw    ?,?
  34. rCX    dw    ?,?
  35. rAX    dw    ?,?
  36. rFlags    dw    ?
  37. rES    dw    ?
  38. rDS    dw    ?
  39. rFS    dw    ?
  40. rGS    dw    ?
  41. rIP    dw    ?
  42. rCS    dw    ?
  43. rSP    dw    ?
  44. rSS    dw    ?
  45. regs    ends
  46.  
  47. ;*--------------------------------------------------------------*
  48.     start_data16
  49.  
  50.     extrn    _tss_ptr:word
  51.     extrn    _screen_seg:word
  52.     extrn    _topline_info:word
  53.  
  54. goProtectMode    dd    ?        ;Location of far call routine
  55. realRegs    regs    <>
  56. selfSP        dw    ?
  57. selfSS        dw    ?
  58. ss_lim        dd    0
  59. forced        db    0
  60.  
  61. maxmem_buffer    dw    24 dup(?)
  62.  
  63.     end_data16
  64. ;*--------------------------------------------------------------*
  65.     start_code16
  66.  
  67.     assume    cs:_TEXT,ds:DGROUP
  68.  
  69. numberException    equ    16        ;Number we ever want to handle
  70. selfDS        dw    ?        ;Protected mode 16bit selector to real
  71.  
  72. ;*--------------------------------------------------------------*
  73. ;*    DPMI
  74. ;* Syntax:
  75. ;*    int initDPMI(DPMIinfo* info)
  76. ;* Argument(s):
  77. ;*    "info" DPMI host
  78. ;* Result(s):
  79. ;*    DPMI
  80. ;*     1  0
  81. ;*--------------------------------------------------------------*
  82.     public    _initDPMI
  83. _initDPMI    proc near
  84.     push    bp
  85.     mov    bp,sp
  86.     push    si
  87.     push    di
  88.     mov    realRegs.rCS,cs    ;Remember segment registers
  89.     mov    realRegs.rDS,ds
  90.     mov    realRegs.rSS,ss
  91.  
  92.     mov    ax,1687h    ; Detect DPMI and get Real to Prot Mode Entry
  93.     int    2fh
  94.     and    ax,ax        ; DPMI successful?  AX == 0 means yes
  95.     jnz    @@failed_initDPMI
  96.     test    bx,1        ; 32Bit programs supported has "1" in bit 0
  97.     jz    @@failed_initDPMI
  98.     mov    word ptr goProtectMode[0],di
  99.     mov    word ptr goProtectMode[2],es
  100.     mov    bx,si        ; number of paragraphs required DPMI host data
  101.     mov    ah,48h
  102.     int    21h
  103.     jc    @@failed_initDPMI
  104.     mov    es,ax        ; Real mode segment of DPMI host data area
  105.     mov    ax,1        ; We want a 32Bit application
  106.     call    goProtectMode
  107.     jc    short @@failed_initDPMI
  108.  
  109.     mov    bx,cs            ;Protected mode cs
  110.     mov    ax,000Ah        ;Create alias descriptor we can write
  111.     int    31h
  112.     jc    short @@failed_initDPMI
  113.     mov    es,ax            ;Alias for our code segment
  114.     assume    es:_TEXT
  115.     mov    es:selfDS,ds        ;In protected mode can't write cs!
  116.     assume    es:nothing
  117.     mov    bx,ax            ;Alias for code segment not needed
  118.     mov    ax,0001h        ;Free LDT descriptor
  119.     int    31h
  120.     mov    selfSS,ss        ;Save protected mode ss selector
  121.  
  122.     mov    ax,0400h        ; get DPMI version and flags
  123.     int    31h
  124.     mov    di,word ptr [bp][4]    ; "info"
  125.     mov    word ptr [di].vers,ax
  126.     mov    [di].flags,bx
  127.     xor    ch,ch
  128.     mov    [di].cpu,cx
  129.     mov    word ptr [di].PIC,dx
  130.  
  131.     mov    ax,0900h        ;Disable virtual interrupt
  132.     int    31h
  133.     mov    ax,1
  134.     jmp    short @@done_initDPMI
  135. @@failed_initDPMI:
  136.     xor    ax,ax
  137. @@done_initDPMI:
  138.     pop    di
  139.     pop    si
  140.     pop    bp
  141.     ret
  142. _initDPMI    endp
  143.  
  144.  
  145. ;*--------------------------------------------------------------*
  146. ;* Syntax:
  147. ;*    void uninitDPMI(int retcode)
  148. ;* Argument(s):
  149. ;*    "retcode" exit()
  150. ;*--------------------------------------------------------------*
  151.     public    _uninitDPMI
  152. _uninitDPMI    proc    near
  153.     push    bp
  154.     mov    bp,sp
  155.     mov    ax,0901h        ; Enable virtual interrupts
  156.     int    31h
  157.     mov    ax,word ptr [bp][4]    ; "retcode"
  158.     mov    ah,4ch            ; Terminate program & prot mode
  159.     int    21h
  160. _uninitDPMI    endp
  161.  
  162. ;*--------------------------------------------------------------*
  163. ;* Syntax:
  164. ;*    void DPMIrealMode(void)
  165. ;*--------------------------------------------------------------*
  166.     public    _DPMIrealMode
  167. _DPMIrealMode    proc    near
  168.     pop    bx        ;Where to return from this procedure
  169.     mov    realRegs.rBX,bx
  170.     mov    realRegs.rSI,si
  171.     mov    realRegs.rDI,di
  172.     mov    realRegs.rBP,bp
  173.     mov    realRegs.rSP,sp
  174.     mov    realRegs.rIP,offset _TEXT:@@realModeEntry
  175.     mov    realRegs.rFlags,0202h
  176.     xor    bx,bx        ;No reset of controllers or A20 line
  177.     xor    cx,cx        ;Don't copy any words from prot stack 
  178.     push    ds
  179.     pop    es        ;ES:EDI = Selector:Offset Real mode call struct
  180.     mov    edi,offset DGROUP:realRegs
  181.     mov    ax,0301h    ; far call to real mode procedure
  182.     int    31h
  183.     mov    si,realRegs.rSI    ; We have returned via DPMIprotectedMode
  184.     mov    di,realRegs.rDI
  185.     movzx    ebp,realRegs.rBP
  186.     movzx    esp,realRegs.rSP
  187.     jmp    realRegs.rBX    ; stored by DPMIprotectedMode() below
  188. @@realModeEntry:
  189.     pop    goProtectMode    ; Address to return from real mode callback
  190.  
  191.     cmp    _topline_info,0
  192.     je    no_topline1
  193.     push    es
  194.     push    ax
  195.     mov    ax,_screen_seg
  196.     mov    es,ax
  197.     mov    word ptr es:[0], 0b00h+'R'
  198.     mov    word ptr es:[2], 0b00h+' '
  199.     pop    ax
  200.     pop    es
  201. no_topline1:
  202.     push    bx        ; Address stored in realRegs above
  203.     ret            ; DPMIrealMode()
  204. _DPMIrealMode    endp
  205.  
  206. ;*--------------------------------------------------------------*
  207. ;* Syntax:
  208. ;*    void DPMIprotectedMode(void)
  209. ;*--------------------------------------------------------------*
  210.     public    _DPMIprotectedMode
  211. _DPMIprotectedMode    proc    near
  212.     cmp    _topline_info,0
  213.     je    no_topline2
  214.     push    ax
  215.     push    es
  216.     mov    ax,_screen_seg
  217.     mov    es,ax
  218.     mov    word ptr es:[2], 0b00h+'P'
  219.     mov    word ptr es:[0], 0b00h+' '
  220.     pop    es
  221.     pop    ax
  222. no_topline2:
  223.     pop    bx            ;Return point (will be used in
  224.     mov    realRegs.rBX,bx        ;  DPMIrealMode above)
  225.     mov    realRegs.rSI,si
  226.     mov    realRegs.rDI,di
  227.     mov    realRegs.rBP,bp
  228.     mov    realRegs.rSP,sp
  229.     jmp    goProtectMode    ;Saved retf address from real mode callback
  230. _DPMIprotectedMode    endp
  231.  
  232. ;*--------------------------------------------------------------*
  233. ;* Syntax:
  234. ;*    void DPMIexecute(void)
  235. ;* Note(s):
  236. ;*    We will return from this call in handlerCommon
  237. ;*--------------------------------------------------------------*
  238.     public    _DPMIexecute
  239. _DPMIexecute    proc    near
  240.     push    bp            ; These 3 registers pushed here are
  241.     push    si            ; popped in handlerCommon_done
  242.     push    di
  243.  
  244.     mov    selfSP,sp
  245.     call    _DPMIprotectedMode    ; Switch to 16 bit protected mode
  246.     mov    bx,_tss_ptr
  247.     mov    ss,[bx].tss_ss
  248.     mov    esp,[bx].tss_esp
  249.     push    [bx].tss_eflags        ; Flags to load (by iretd below)
  250.     push    dword ptr [bx].tss_cs    ; CS to execute (32 bit)
  251.     push    [bx].tss_eip        ; EIP to execute (32 bit)
  252.     mov    eax,[bx].tss_eax
  253.     mov    ecx,[bx].tss_ebx
  254.     push    ecx
  255.     mov    ecx,[bx].tss_ecx
  256.     mov    edx,[bx].tss_edx
  257.     mov    ebp,[bx].tss_ebp
  258.     mov    esi,[bx].tss_esi
  259.     mov    edi,[bx].tss_edi
  260.     mov    es,[bx].tss_es
  261.     mov    fs,[bx].tss_fs
  262.     mov    gs,[bx].tss_gs
  263.     mov    ds,[bx].tss_ds
  264.     pop    ebx
  265.  
  266.     push    eax
  267.     mov    ax,0901h        ; Enable virtual interrupts
  268.     int    31h
  269.     pop    eax
  270.  
  271.     iretd                ; Jump to values pushed on stack
  272. _DPMIexecute    endp
  273.  
  274. ;*--------------------------------------------------------------*
  275. ;*
  276. ;* Syntax:
  277. ;*    word32 DPMImaxmem()
  278. ;* Result(s):
  279. ;*     returns number of bytes of memory left
  280. ;*--------------------------------------------------------------*
  281.     public    _DPMImaxmem
  282. _DPMImaxmem    proc    near
  283.     push    bp
  284.     mov    bp,sp
  285.     push    si
  286.     push    di
  287.     mov    ax,0500h            ; Get Free Memory Information
  288.     mov    di, offset maxmem_buffer
  289.     int    31h
  290.     mov    di,[bp+4]
  291.     mov    si,offset maxmem_buffer
  292.     movsd
  293.     add    si,16
  294.     movsd
  295.     add    si,8
  296.     movsd
  297.     pop    di
  298.     pop    si
  299.     pop    bp
  300.     ret
  301. _DPMImaxmem    endp
  302.  
  303. ;*--------------------------------------------------------------*
  304. ;*
  305. ;* Syntax:
  306. ;*    int DPMIalloc(DPMImemory* mem, word32 bytes)
  307. ;* Argument(s):
  308. ;*    "mem"
  309. ;*    "bytes"
  310. ;* Result(s):
  311. ;*     returns 1 or 0 to flag success or failure
  312. ;*     "mem"
  313. ;* Note(s):
  314. ;*    DPMIfree() will release the memory
  315. ;*--------------------------------------------------------------*
  316.     public    _DPMIalloc
  317. _DPMIalloc    proc    near
  318.     push    bp
  319.     mov    bp,sp
  320.     push    si
  321.     push    di
  322.     mov    ax,0501h            ; Allocate memory block
  323. alloc_common:
  324.     mov    cx,word ptr [bp][4+2][0]    ; "bytes" to allocate
  325.     mov    bx,word ptr [bp][4+2][2]
  326.     int    31h                ; returns BX:CX SI:DI
  327.     jc    short @@failed_DPMIalloc
  328.     push    bx                ; save til later
  329.     mov    bx,word ptr [bp][4]        ; "mem" address
  330.     mov    word ptr [bx].handle[0],di
  331.     mov    word ptr [bx].handle[2],si
  332.     mov    word ptr [bx].address[0],cx
  333.     pop    ax
  334.     mov    word ptr [bx].address[2],ax
  335.     mov    ecx,dword ptr [bp][4+2]        ; copy "bytes" into struct
  336.     mov    [bx].bytes,ecx
  337.     mov    ax,1                ; success
  338.     jmp    short @@done_DPMIalloc
  339. @@failed_DPMIalloc:
  340.     xor    ax,ax                ; failure
  341. @@done_DPMIalloc:
  342.     pop    di
  343.     pop    si
  344.     pop    bp
  345.     ret
  346. _DPMIalloc    endp
  347.  
  348. ;*--------------------------------------------------------------*
  349. ;*
  350. ;* Syntax:
  351. ;*    int DPMIrealloc(DPMImemory* mem, word32 bytes)
  352. ;* Argument(s):
  353. ;*    "mem"
  354. ;*    "bytes"
  355. ;* Result(s):
  356. ;*     returns 1 or 0 to flag success or failure
  357. ;*     "mem"
  358. ;* Note(s):
  359. ;*    DPMIfree() will release the memory
  360. ;*--------------------------------------------------------------*
  361.     public    _DPMIrealloc
  362. _DPMIrealloc    proc    near
  363.     push    bp
  364.     mov    bp,sp
  365.     push    si
  366.     push    di
  367.     mov    bx,word ptr [bp][4]        ; "mem" address
  368.     mov    di,word ptr [bx].handle[0]
  369.     mov    si,word ptr [bx].handle[2]
  370.     mov    ax,0503h            ; Resize memory block
  371.     jmp    short alloc_common
  372. _DPMIrealloc    endp
  373.  
  374. ;*--------------------------------------------------------------*
  375. ;*
  376. ;* Syntax:
  377. ;*    void DPMIfree(DPMImemory* mem)
  378. ;* Argument(s):
  379. ;*    "mem"
  380. ;* Note(s):
  381. ;*    DPMIalloc(), DPMIrealloc() allocate the memory block
  382. ;*--------------------------------------------------------------*
  383.     public    _DPMIfree
  384. _DPMIfree    proc    near
  385.     push    bp
  386.     mov    bp,sp
  387.     push    si
  388.     push    di
  389.     mov    bx,word ptr [bp][4]        ; "mem" address
  390.     mov    di,word ptr [bx].handle[0]
  391.     mov    si,word ptr [bx].handle[2]
  392.     mov    ax,0502h            ; Free memory block
  393.     int    31h
  394.     pop    di
  395.     pop    si
  396.     pop    bp
  397.     ret
  398. _DPMIfree    endp
  399.  
  400. ;*--------------------------------------------------------------*
  401. ;*
  402. ;* Syntax:
  403. ;*    word16 DPMIselector(word16 number)
  404. ;* Argument(s):
  405. ;*    "number"
  406. ;* Result(s):
  407. ;*    base value of contiguous LDT desciptors
  408. ;*--------------------------------------------------------------*
  409.     public    _DPMIselector
  410. _DPMIselector    proc    near
  411.     push    bp
  412.     mov    bp,sp
  413.     mov    cx,word ptr [bp][4]        ;"number" to allocate
  414.     mov    ax,0000h            ; Allocate LDT Descriptors
  415.     int    31h                ; returns AX
  416.     jnc    short @@done_DPMIselector
  417.     xor    ax,ax
  418. @@done_DPMIselector:
  419.     pop    bp
  420.     ret
  421. _DPMIselector    endp
  422.  
  423. ;*--------------------------------------------------------------*
  424. ;*
  425. ;* Syntax:
  426. ;*    void DPMIassignSelector(word16 selector, word16 type, word32 base, word32 limit)
  427. ;* Argument(s):
  428. ;*    "selector"
  429. ;*    "type"
  430. ;*    "base"
  431. ;*    "limit"
  432. ;*--------------------------------------------------------------*
  433.     public    _DPMIassignSelector
  434. _DPMIassignSelector    proc    near
  435.     push    bp
  436.     mov    bp,sp
  437.     mov    bx,word ptr [bp][4]        ; "selector"
  438.     mov    dx,word ptr [bp][4+2+2][0]
  439.     mov    cx,word ptr [bp][4+2+2][2]    ; "base"
  440.     mov    ax,0007h            ; Set segment base
  441.     int    31h
  442.     jc    short @@err_DPMIassignSelector
  443.  
  444.     lar    ax,bx                ; get priv level of selector bx
  445.     and    ah,60h                ; Mask all except CPL
  446.     mov    cx,word ptr [bp][4+2]        ; "type"
  447.     and    cl,9fh                ; Clear passed CPL
  448.     or    cl,ah                ; Insert CPL of selector
  449.     mov    ax,0009h            ; Set descriptor access rights
  450.     int    31h
  451.     jc    short @@err_DPMIassignSelector
  452.  
  453.     mov    dx,word ptr [bp][4+2+2+4][0]
  454.     mov    cx,word ptr [bp][4+2+2+4][2]    ; "limit"
  455.     mov    ax,0008h            ; Set segment limit
  456.  
  457. selector_common:
  458.     int    31h
  459.     jc    short @@err_DPMIassignSelector
  460.  
  461.     mov    ax,1
  462.     jmp    short @@done_DPMIassignSelector
  463. @@err_DPMIassignSelector:
  464.     xor    ax,ax
  465. @@done_DPMIassignSelector:
  466.     pop    bp
  467.     ret
  468. _DPMIassignSelector    endp
  469.  
  470. ;*--------------------------------------------------------------*
  471. ;*
  472. ;* Syntax:
  473. ;*    void DPMISelectorBase(word16 selector, word32 base)
  474. ;* Argument(s):
  475. ;*    "selector"
  476. ;*    "base"
  477. ;*--------------------------------------------------------------*
  478.     public    _DPMISelectorBase
  479. _DPMISelectorBase    proc    near
  480.     push    bp
  481.     mov    bp,sp
  482.     mov    bx,word ptr [bp][4]        ; "selector"
  483.     mov    dx,word ptr [bp][4+2][0]
  484.     mov    cx,word ptr [bp][4+2][2]    ; "base"
  485.     mov    ax,0007h            ; Set segment base
  486.     jmp    short selector_common
  487. _DPMISelectorBase    endp
  488.  
  489. ;*--------------------------------------------------------------*
  490. ;*
  491. ;* Syntax:
  492. ;*    void DPMIchangeException(word8 no, DPMIaddress* handler)
  493. ;* Argument(s):
  494. ;*    "no"
  495. ;*    "handler"
  496. ;*--------------------------------------------------------------*
  497.     public    _DPMIchangeException
  498. _DPMIchangeException    proc    near
  499.     push    bp
  500.     mov    bp,sp
  501.     mov    ax,0202h        ; Get exception handler vector
  502.     mov    bx,word ptr [bp][4]    ; "no"
  503.     int    31h            ; return value in CX:EDX
  504.     mov    ax,0203h        ; Set exception handler vector
  505. change_common:
  506.     push    cx            ; Save it
  507.     push    edx
  508.     mov    bx,word ptr [bp][4+2]    ; "handler" struct address
  509.     mov    edx,dword ptr [bx][0]
  510.     mov    cx,word ptr [bx][4]
  511.     mov    bx,word ptr [bp][4]    ; "no"
  512.     int    31h            ; Do the change!
  513.     mov    bx,word ptr [bp][4+2]    ; "handler" struct address
  514.     pop    edx            ; original "handler" offset
  515.     mov    dword ptr [bx][0],edx
  516.     pop    cx            ; original "handler" segment
  517.     mov    word ptr [bx][4],cx
  518.     pop    bp
  519.     ret
  520. _DPMIchangeException    endp
  521.  
  522. ;*--------------------------------------------------------------*
  523. ;*
  524. ;* Syntax:
  525. ;*    void DPMIchangeInterrupt(word8 no, DPMIaddress* handler)
  526. ;* Argument(s):
  527. ;*    "no"
  528. ;*    "handler"
  529. ;*--------------------------------------------------------------*
  530.     public    _DPMIchangeInterrupt
  531. _DPMIchangeInterrupt    proc    near
  532.     push    bp
  533.     mov    bp,sp
  534.     mov    ax,0204h        ; Get protected mode interrupt vector
  535.     mov    bx,word ptr [bp][4]    ; "no"
  536.     int    31h            ; return value in CX:EDX
  537.     mov    ax,0205h        ; Set protected mode interrupt vector
  538.     jmp    short change_common
  539. _DPMIchangeInterrupt    endp
  540.  
  541. ;*--------------------------------------------------------------*
  542. ;*
  543. ;* Syntax:
  544. ;*    void DPMIhandlerNPX(DPMIaddress* handler)
  545. ;* Argument(s):
  546. ;*    "handler"
  547. ;* Notes:
  548. ;*      This returns the handler address "no" for NPX hardware exceptions
  549. ;*--------------------------------------------------------------*
  550.     public    _DPMIhandlerNPX
  551. _DPMIhandlerNPX    proc    near
  552.     push    bp
  553.     mov    bp,sp
  554.     mov    bx,word ptr [bp][4]    ; "handler"
  555.     mov    dword ptr [bx][0],offset _TEXT:i75hdlr
  556.     mov    word ptr [bx][4],cs
  557.     pop    bp
  558.     ret
  559. i75hdlr:
  560.     push    eax
  561.     xor    ax,ax
  562.     out    0f0h,al
  563.     mov    al,20h
  564.     out    0a0h,al
  565.     out    020h,al
  566.     mov    al,75h
  567.     call    causeException
  568.     pop    eax
  569.     sti
  570.     iretd
  571. _DPMIhandlerNPX    endp
  572.  
  573. ; code to disable execution
  574. causeException    proc    near
  575.     push    ebx
  576.     push    cx
  577.     push    dx
  578.     push    ds
  579.     mov    ds,cs:selfDS
  580.     mov    forced,al        ; Indicate a fake exception
  581.     mov    bx,_tss_ptr
  582.     movzx    ebx,[bx].tss_ss
  583.     lsl    eax,ebx
  584.     mov    ss_lim,eax
  585.     xor    cx,0fffh
  586.     mov    dx,0ffffh
  587.     mov    ax,0008h        ;Set segment limit
  588.     int    31h
  589.     pop    ds
  590.     pop    dx
  591.     pop    cx
  592.     pop    ebx
  593.     ret
  594. causeException    endp
  595.  
  596. ;*--------------------------------------------------------------*
  597. ;*
  598. ;* Syntax:
  599. ;*    void DPMIehandler(word8 no, DPMIaddress* handler)
  600. ;* Argument(s):
  601. ;*    "no"
  602. ;*    "handler"
  603. ;* Notes:
  604. ;*      This returns the handler address "no" for exceptions.
  605. ;*--------------------------------------------------------------*
  606.     public    _DPMIehandler
  607. _DPMIehandler    proc    near
  608.     push    bp
  609.     mov    bp,sp
  610.     mov    ax,word ptr [bp][4]    ; "no"
  611.     xor    ah,ah
  612.     mov    dx,sizeOfeHandler
  613.     mul    dx
  614.     add    ax,offset _TEXT:ehandlerTable
  615.     jmp    short gethandleraddr
  616.  
  617. ehandler    macro    n
  618.     push    n
  619.     jmp    short ehandlerCommon
  620.     endm
  621.  
  622. ehandlerTable:
  623.     ehandler    0
  624. sizeOfeHandler    equ    $-offset ehandlerTable
  625.     x = 1
  626.     rept numberException
  627.     ehandler    x
  628.     x = x + 1
  629.     endm
  630. ehandlerCommon:
  631.     jmp    handlerCommon
  632. _DPMIehandler    endp
  633.  
  634. ;*--------------------------------------------------------------*
  635. ;*
  636. ;* Syntax:
  637. ;*    void DPMIhandler(word8 no, DPMIaddress* handler)
  638. ;* Argument(s):
  639. ;*    "no"
  640. ;*    "handler"
  641. ;* Notes:
  642. ;*      This returns the handler address "no" for interrupts.
  643. ;*--------------------------------------------------------------*
  644.     public    _DPMIhandler
  645. _DPMIhandler    proc    near
  646.     push    bp
  647.     mov    bp,sp
  648.     mov    ax,word ptr [bp][4]    ; "no"
  649.     xor    ah,ah
  650.     mov    dx,sizeOfHandler
  651.     mul    dx
  652.     add    ax,offset _TEXT:handlerTable
  653. gethandleraddr:
  654.     mov    bx,word ptr [bp][4+2]    ; "handler"
  655.     mov    word ptr [bx][0],ax
  656.     mov    word ptr [bx][2],dx
  657.     mov    word ptr [bx][4],cs
  658.     pop    bp
  659.     ret
  660.  
  661. handler    macro    n
  662.     push    n
  663.     jmp    handlerCommon
  664.     endm
  665.  
  666. handlerTable:
  667.     handler    256
  668. sizeOfHandler    equ    $-offset handlerTable
  669.     x = 257
  670.     rept 255
  671.     handler    x
  672.     x = x + 1
  673.     endm
  674. _DPMIhandler    endp
  675.  
  676. ;*
  677. ;* Note(s):
  678. ;*    This code is called any time an interrupt or execption occurs in the
  679. ;*    32 bit protected mode code.  The interrupt or exception number is
  680. ;*    pushed on the stack (with the high byte being 1 for interrupt).
  681. ;*    This is the only way code may escape the 32 bit mode entered via
  682. ;*    DPMIexecute().
  683. ;*
  684. handlerCommon    proc    near
  685.     push    ax
  686.     mov    ax,0900h            ;Disable virtual interrupts
  687.     int    31h
  688.     pop    ax
  689.     push    ebx                ;tss access
  690.     push    ds
  691.     mov    ds,cs:selfDS
  692.     mov    bx,_tss_ptr
  693.     pop    word ptr [bx].tss_ds
  694.     pop    [bx].tss_ebx
  695.  
  696.     mov    [bx].tss_es,es
  697.     mov    [bx].tss_fs,fs
  698.     mov    [bx].tss_gs,gs
  699.     mov    [bx].tss_esi,esi
  700.     mov    [bx].tss_edi,edi
  701.     mov    [bx].tss_ebp,ebp
  702.     mov    [bx].tss_edx,edx
  703.     mov    [bx].tss_ecx,ecx
  704.     mov    [bx].tss_eax,eax
  705.     
  706.     pop    ax
  707.     mov    [bx].tss_irqn,al
  708.  
  709.     or    ah,ah
  710.     jnz    @@handlerCommon_interrupt
  711.  
  712. ; Exception only code:
  713.     push    ebp
  714.     mov    ebp,esp
  715.  
  716.     cmp    al,12                ; Stack fault?
  717.     jne    not_forced
  718.     mov    al,forced            ; Did we force this in hw int?
  719.     cmp    al,0
  720.     jz    not_forced
  721.     mov    [bx].tss_irqn,al        ; Real exception
  722.     mov    forced,0            ; Its handled
  723.     call    limitFix            ; Fix the limit
  724.  
  725. not_forced:
  726.  
  727.     mov    eax,dword ptr [ebp][12]
  728.     mov    [bx].tss_error,eax
  729.     mov    eax,dword ptr [ebp][12+4]
  730.     mov    [bx].tss_eip,eax
  731.     mov    ax,word ptr [ebp][12+4+4]
  732.     mov    [bx].tss_cs,ax
  733.  
  734.     mov    eax,dword ptr [ebp][12+4+4+4]
  735.     and     ax,0FEFFh                ; clear trace flag
  736.     or      ax, 0200h                ; set iret flag
  737.     mov    [bx].tss_eflags,eax
  738.     mov     dword ptr [ebp][12+4+4+4],eax        ; put back on dpmi-stack
  739.  
  740.     mov     eax, dword ptr [ebp+28]
  741.     mov     [bx].tss_esp, eax
  742.     mov     ax,word ptr [ebp+32]
  743.     mov     word ptr [bx].tss_ss, ax
  744.  
  745.     mov    dword ptr [ebp][16],offset _TEXT:@@handlerCommon_exception
  746.     mov    word ptr [ebp][16+4],cs            ; Set CS:EIP on stack
  747.  
  748. ; Change to 16 bit stack on return from exception (may be 32bit stack exception)
  749.     movzx   eax,selfSP
  750.     mov     dword ptr [ebp+28],eax              ; set ESP on stack
  751.     mov     ax,selfSS
  752.     mov     word ptr [ebp+32],ax            ; set SS on stack
  753.      
  754.     mov     eax,dword ptr [bx].tss_eax        ; restore regs...
  755.     push    dword ptr [bx].tss_ebx
  756.     push    word ptr [bx].tss_ds
  757.     pop     ds
  758.     pop    ebx
  759.  
  760.     pop    ebp
  761.     db    66h
  762.     retf
  763.  
  764. @@handlerCommon_exception:
  765.     mov    ds,cs:selfDS
  766.     push    0                    ; Indicate exception
  767.     jmp    short @@handlerCommon_done
  768.  
  769. @@handlerCommon_interrupt:
  770.     pop    [bx].tss_eip
  771.     pop    dword ptr [bx].tss_cs
  772.     pop    [bx].tss_eflags
  773.     mov    ds,cs:selfDS
  774.     mov    bx,_tss_ptr
  775.     mov    [bx].tss_ss,ss
  776.     mov    [bx].tss_esp,esp
  777.     mov    ss,selfSS
  778.     movzx    esp,selfSP
  779.     push    1                    ; Indicate interrupt
  780. @@handlerCommon_done:
  781.     xor    ebp,ebp
  782.     call    _DPMIrealMode
  783.     pop    ax
  784.  
  785.     pop    di                ; C needs these registers saved
  786.     pop    si
  787.     pop    bp
  788.     ret                    ; DPMIexecute() return point
  789. handlerCommon    endp
  790.  
  791. ; Code to restore ss limit
  792. limitFix    proc    near
  793.     push    bx
  794.     push    cx
  795.     push    dx
  796. ;    mov    bx,[bx].tss_ss        ;We didn't store it yet, but...
  797.     mov     bx,word ptr [ebp+32]    ;Stack selector 
  798.     mov    dx,word ptr ss_lim
  799.     mov    cx,word ptr ss_lim+2
  800.     mov    ax,0008h        ;Set segment limit
  801.     int    31h
  802.     pop    dx
  803.     pop    cx
  804.     pop    bx
  805.     ret
  806. limitFix    endp
  807.  
  808. ;*--------------------------------------------------------------*
  809. ;* Syntax:
  810. ;*    int DPMIsetBreak(word16 sizetype, word32 addr);
  811. ;* Argument(s):
  812. ;*    "sizetype" contains contents of DX - both size and type of breakpoing
  813. ;*    "addr"     contains 32 bit address of breakpoint
  814. ;*--------------------------------------------------------------*
  815.     public    _DPMIsetBreak
  816. _DPMIsetBreak    proc    near
  817.     push    bp
  818.     mov    bp,sp
  819.     call    _DPMIprotectedMode
  820.     mov    dx,word ptr [bp][4]        ; set size and type
  821.     mov    cx,word ptr [bp][4+2]        ; Move 32 bit "addr" to BX:CX
  822.     mov    bx,word ptr [bp][4+2+2]        ; Move 32 bit "addr" to BX:CX
  823.     mov    ax,0B00h            ; Set debug watch point
  824.     int    31h
  825.     jnc    short @@done_DPMIsetBreak
  826.     mov    bx,-1
  827. @@done_DPMIsetBreak:
  828.     push    bx
  829.     call    _DPMIrealMode
  830.     pop    ax
  831.     pop    bp
  832.     ret
  833. _DPMIsetBreak    endp
  834.  
  835. ;*--------------------------------------------------------------*
  836. ;* Syntax:
  837. ;*    int DPMIcancelBreak(int handle);
  838. ;* Argument(s):
  839. ;*    "handle"  contains handle number to cancel and return state
  840. ;*--------------------------------------------------------------*
  841.     public    _DPMIcancelBreak
  842. _DPMIcancelBreak    proc    near
  843.     push    bp
  844.     mov    bp,sp
  845.     call    _DPMIprotectedMode
  846.     mov    bx,word ptr [bp][4]        ; watchpoint handle
  847.     mov    ax,0B02h            ; Get debug watch point state
  848.     int    31h
  849.     jnc    short @@ok_DPMIcancelBreak
  850.     xor    ax,ax                ;Not active if error
  851. @@ok_DPMIcancelBreak:
  852.     and    ax,1                ;Clear all but low bit
  853.     push    ax                ;Watch point execution state
  854.     mov    ax,0B01h            ;Clear debug watch point state
  855.     int    31h
  856.     call    _DPMIrealMode
  857.     pop    ax
  858.     pop    bp
  859.     ret
  860. _DPMIcancelBreak    endp
  861.  
  862. ;*--------------------------------------------------------------*
  863. ;*
  864. ;* Syntax:
  865. ;*    void Pmemget(word16 sel, word32 off, void* addr, word16 bytes)
  866. ;* Argument(s):
  867. ;*    "sel"
  868. ;*    "off"
  869. ;*    "addr"
  870. ;*    "bytes"
  871. ;*--------------------------------------------------------------*
  872.     public    _Pmemget
  873. _Pmemget    proc    near
  874.     push    bp
  875.     mov    bp,sp
  876.     push    si
  877.     push    di
  878.     call    _DPMIprotectedMode
  879.     push    ds
  880.     push    es
  881.     mov    ax,ds                ; ES = curr DS (16 bit area)
  882.     mov    es,ax
  883.     mov    ds,word ptr [bp][4]        ; Move 32 bit "sel" to DS
  884.     mov    esi,dword ptr [bp][4+2]        ; Move 32 bit "off" to ESI
  885.     movzx    edi,word ptr [bp][4+2+4]    ; 16 bit "addr" (ES:EDI)
  886. move_common:
  887.     cld
  888.     movzx    ecx,word ptr [bp][4+2+4+2]    ; "bytes"
  889.     shr    cx,2                ; Get multiple of 4
  890.     jcxz    short @@little_Pmemmove
  891.     db    67h                ; Use esi, edi (32 bit)
  892.     rep    movsd
  893. @@little_Pmemmove:
  894.     movzx    ecx,word ptr [bp][4+2+4+2]    ; "bytes"
  895.     and    cx,3                ; Get remainder of 4
  896.     jcxz    short @@done_Pmemmove
  897.     db    67h                ; Use esi, edi (32 bit)
  898.     rep    movsb
  899. @@done_Pmemmove:
  900.     pop    es
  901.     pop    ds
  902.     call    _DPMIrealMode
  903.     pop    di
  904.     pop    si
  905.     pop    bp
  906.     ret
  907. _Pmemget    endp
  908.  
  909. ;*--------------------------------------------------------------*
  910. ;*
  911. ;* Syntax:
  912. ;*    void Pmemput(word16 sel, word32 off, const void* addr, word16 bytes)
  913. ;* Argument(s):
  914. ;*    "sel"
  915. ;*    "off"
  916. ;*    "addr"
  917. ;*    "bytes"
  918. ;*--------------------------------------------------------------*
  919.     public    _Pmemput
  920. _Pmemput    proc    near
  921.     push    bp
  922.     mov    bp,sp
  923.     push    si
  924.     push    di
  925.     call    _DPMIprotectedMode
  926.     push    ds                ; Not modified but common pop
  927.     push    es
  928.     mov    es,word ptr [bp][4]        ; move 32 bit "sel" to ES
  929.     mov    edi,dword ptr [bp][4+2]        ; move 32 bit "off" to EDI
  930.     movzx    esi,word ptr [bp][4+2+4]    ; 16 bit "addr" (DS:ESI)
  931.     jmp    short move_common
  932. _Pmemput    endp
  933.  
  934. ;*--------------------------------------------------------------*
  935. ;*
  936. ;* Syntax:
  937. ;*    void Pmemset(word16 sel, word32 off, word8 value, word32 bytes)
  938. ;*    "sel"
  939. ;*    "off"
  940. ;*    "value"
  941. ;*    "bytes"
  942. ;*--------------------------------------------------------------*
  943.     public    _Pmemset
  944. _Pmemset    proc    near
  945.     push    bp
  946.     mov    bp,sp
  947.     push    di
  948.     call    _DPMIprotectedMode
  949.     push    es
  950.     mov    es,word ptr [bp][4]    ; "sel"
  951.     mov    edi,dword ptr [bp][4+2]    ; "off"
  952.     mov    ax,word ptr [bp][4+2+4]    ; "value"
  953.     mov    ah,al
  954.     push    ax
  955.     push    ax
  956.     pop    eax
  957.     cld
  958.     mov    ecx,dword ptr [bp][4+2+4+2]    ; "bytes"
  959.     shr    ecx,2
  960.     jecxz    short @@little_Pmemset
  961.     db    67h        ; edi
  962.     rep    stosd
  963. @@little_Pmemset:
  964.     mov    ecx,dword ptr [bp][4+2+4+2]    ; "bytes"
  965.     and    ecx,3
  966.     jcxz    short @@done_Pmemset
  967.     db    67h        ; edi
  968.     rep    stosb
  969. @@done_Pmemset:
  970.     pop    es
  971.     call    _DPMIrealMode
  972.     pop    di
  973.     pop    bp
  974.     ret
  975. _Pmemset    endp
  976.  
  977. ;*--------------------------------------------------------------*
  978. ;*
  979. ;* Syntax:
  980. ;*    word16 Pmemscan(word16 sel, word32 off, word8 value, word16 bytes)
  981. ;*    "sel"
  982. ;*    "off"
  983. ;*    "value"
  984. ;*    "bytes"
  985. ;*--------------------------------------------------------------*
  986.     public    _Pmemscan
  987. _Pmemscan    proc    near
  988.     push    bp
  989.     mov    bp,sp
  990.     push    di
  991.     call    _DPMIprotectedMode
  992.     push    es
  993.     mov    es,word ptr [bp][4]    ; "sel"
  994.     mov    edi,dword ptr [bp][4+2]    ; "off"
  995.     mov    ax,word ptr [bp][4+2+4]    ; "value"
  996.     cld
  997.     movzx    ecx,word ptr [bp][4+2+4+2]    ; "bytes"
  998.     db    67h        ; edi
  999.     repne    scasb
  1000.     mov    di,0
  1001.     jne    short @@done_Pmemscan
  1002.     mov    di,word ptr [bp][4+2+4+2]    ; "bytes"
  1003.     sub    di,cx
  1004. @@done_Pmemscan:
  1005.     pop    es
  1006.     call    _DPMIrealMode
  1007.     mov    ax,di
  1008.     pop    di
  1009.     pop    bp
  1010.     ret
  1011. _Pmemscan    endp
  1012.  
  1013.     end_code16
  1014. ;*--------------------------------------------------------------*
  1015.     end
  1016.